package com.example.mall.service.impl;
import java.math.BigDecimal;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mall.constants.BaseConstants;
import com.example.mall.domain.Order;
import com.example.mall.domain.PayOrder;
import com.example.mall.dto.PayOrderDto;
import com.example.mall.mapper.PayOrderMapper;
import com.example.mall.query.PageDTO;
import com.example.mall.query.PayOrderQuery;
import com.example.mall.service.IPayOrderService;
import com.example.mall.to.PlaceProductOrderTo;
import com.example.mall.util.AssertUtil;
import com.example.mall.util.CodeGenerateUtils;
import com.example.mall.util.CopyUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 支付订单表 服务实现类
 * </p>
 *
 * @author whale
 * @since 2025-06-03
 */
@Service
@Slf4j
public class PayOrderServiceImpl extends ServiceImpl<PayOrderMapper, PayOrder> implements IPayOrderService {

    @Autowired
    private PayOrderMapper payOrderMapper;
    @Autowired
    private PayServiceImpl payService;

    @Override
    public PageDTO<PayOrderDto> queryPage(PayOrderQuery payOrderQuery) {
        if (payOrderQuery == null) {
            payOrderQuery = new PayOrderQuery();
        }
        Page<PayOrder> page = payOrderQuery.toMpPageByDefaultCreateTimeAsc();
        Page<PayOrder> cartPage = lambdaQuery()
                .like(payOrderQuery.getId()!= null, PayOrder::getId, payOrderQuery.getId())
                .like(payOrderQuery.getAmount()!= null, PayOrder::getAmount, payOrderQuery.getAmount())
                .like(payOrderQuery.getPayType()!= null, PayOrder::getPayType, payOrderQuery.getPayType())
                .like(payOrderQuery.getRelationId()!= null, PayOrder::getRelationId, payOrderQuery.getRelationId())
                .like(payOrderQuery.getOrderNo()!= null, PayOrder::getOrderNo, payOrderQuery.getOrderNo())
                .like(payOrderQuery.getUserId()!= null, PayOrder::getUserId, payOrderQuery.getUserId())
                .like(payOrderQuery.getSubject()!= null, PayOrder::getSubject, payOrderQuery.getSubject())
                .like(payOrderQuery.getExtParams()!= null, PayOrder::getExtParams, payOrderQuery.getExtParams())
                .like(payOrderQuery.getPayStatus()!= null, PayOrder::getPayStatus, payOrderQuery.getPayStatus())
                .orderByDesc(PayOrder::getUpdateTime)
                .page(page);
        return PageDTO.of(cartPage, PayOrderDto.class);
    }

    @Override
    public PayOrder queryPayOrderById(Long id) {
        AssertUtil.isNotNull(id, "id不能为空");
        return payOrderMapper.selectById(id);
    }

    @Override
    public List<PayOrder> queryPayOrderList() {
        return this.list();
    }

    @Override
    public void insert(PayOrderDto payOrderDto) {
        PayOrder payOrder = new PayOrder();
        CopyUtils.copyProperties(payOrderDto, payOrder);
        payOrder.setId(CodeGenerateUtils.generateUniqueId());
        payOrder.setCreateTime(new Date());
        payOrder.setUpdateTime(new Date());
        payOrder.setPayStatus(BaseConstants.NOT_USED);
        payOrderMapper.insert(payOrder);
    }

    @Override
    public void update(PayOrderDto payOrderDto) {
        AssertUtil.isNotNull(payOrderDto.getId(), "id不能为空");
        PayOrder payOrder = payOrderMapper.selectById(payOrderDto.getId());
        AssertUtil.isNotNull(payOrder, "支付订单不存在");
        CopyUtils.copyProperties(payOrderDto, payOrder);
        payOrder.setUpdateTime(new Date());
        payOrderMapper.updateById(payOrder);
    }

    @Override
    public void delete(Long id) {
        AssertUtil.isNotNull(id, "id不能为空");
        PayOrder payOrder = payOrderMapper.selectById(id);
        AssertUtil.isNotNull(payOrder, "支付订单不存在");
        payOrder.setPayStatus(BaseConstants.EXPIRED);
        payOrderMapper.updateById(payOrder);
    }

    @Override
    public void deleteBatch(List<Long> ids) {
        AssertUtil.isNotNull(ids, "ids不能为空");
        List<PayOrder> payOrders = payOrderMapper.selectBatchIds(ids);
        AssertUtil.isNotNull(payOrders, "支付订单不存在");
        for (PayOrder payOrder : payOrders) {
            payOrder.setPayStatus(BaseConstants.EXPIRED);
            payOrderMapper.updateById(payOrder);
        }
    }

    @Override
    public PayOrder selectByOrderNo(String orderNo) {
        AssertUtil.isNotNull(orderNo, "orderNo不能为空");
        LambdaQueryWrapper<PayOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PayOrder::getOrderNo, orderNo);
        return payOrderMapper.selectOne(queryWrapper);
    }

    @Override
    public void savePayOrder(PlaceProductOrderTo placeProductOrderTo) {
        PayOrder payOrder = new PayOrder();
        payOrder.setSubject(placeProductOrderTo.getSubject());
        payOrder.setRelationId(placeProductOrderTo.getRelationId());
        payOrder.setOrderNo(placeProductOrderTo.getOrderNo());
        payOrder.setAmount(placeProductOrderTo.getAmount());
        payOrder.setCreateTime(new Date());
        payOrder.setPayType(placeProductOrderTo.getPayType());
        payOrder.setUserId(placeProductOrderTo.getUserId());
        payOrder.setExtParams(placeProductOrderTo.getExtParams());
        payOrder.setPayStatus(BaseConstants.Pay.STATUS_APPLY);
        payOrderMapper.insert(payOrder);
    }

    @Override
    public PayOrder savePayOrder(Order order) {
        // todo 保存支付订单
        Order orderInfo = new Order();
        orderInfo.setOrderId(0L);
        orderInfo.setUserId(0L);
        orderInfo.setOrderStatus(0);
        orderInfo.setTotalAmount(new BigDecimal("0"));
        orderInfo.setDiscountAmount(new BigDecimal("0"));
        orderInfo.setFinalAmount(new BigDecimal("0"));
        orderInfo.setPaymentMethod("");
        orderInfo.setPaymentStatus(0);
        orderInfo.setCreateDate(new Date());
        orderInfo.setUpdateDate(new Date());
        orderInfo.setOrderNo("");
        orderInfo.setTitle("");


        return null;
    }

    @Override
    public void closeOrder(PlaceProductOrderTo placeProductOrderTo) {
        synchronized (placeProductOrderTo.getOrderNo()){
            LambdaQueryWrapper<PayOrder> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(PayOrder::getOrderNo, placeProductOrderTo.getOrderNo());
            PayOrder payOrder = payOrderMapper.selectOne(queryWrapper);
            if(payOrder.getPayStatus() == BaseConstants.Pay.STATUS_APPLY){
                log.info("支付超时关单，修改支付单状态...");
                payOrder.setPayStatus(BaseConstants.Pay.STATUS_OUT_TIME);
                updateById(payOrder);
                //调用支付宝关单接口
                payService.closeOrder(placeProductOrderTo);
            }
        }
    }
}
